﻿using System;
using System.Workflow.Activities;
using Microsoft.SharePoint.Workflow;
using Microsoft.SharePoint.WorkflowActions;
using PD.ShP.Code.DataModel;

namespace PD.ShP.Workflows
{
    /// <summary>
    /// Represents a workflow that sequentially executes activities to process the invoice.
    /// </summary>
    public sealed partial class InvoiceProcessingWorkflow : SequentialWorkflowActivity, IWorkflowContext
    {
        /// <summary>
        /// The workflow instance identifier.
        /// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.StyleCop.CSharp.MaintainabilityRules", "SA1401:FieldsMustBePrivate", Justification = "Required by workflow and cannot be changed.")]
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.StyleCop.CSharp.NamingRules", "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter", Justification = "Required by workflow and cannot be changed.")]
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Justification = "Required by workflow and cannot be changed.")]
        public Guid workflowId = default(System.Guid);

        /// <summary>
        /// The initial properties of the workflow.
        /// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.StyleCop.CSharp.MaintainabilityRules", "SA1401:FieldsMustBePrivate", Justification = "Required by workflow and cannot be changed.")]
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.StyleCop.CSharp.NamingRules", "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter", Justification = "Required by workflow and cannot be changed.")]
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Justification = "Required by workflow and cannot be changed.")]
        public SPWorkflowActivationProperties workflowProperties = new SPWorkflowActivationProperties();

        /// <summary>
        /// The invoice processing controller.
        /// </summary>
        private InvoiceProcessingController controller;

        /// <summary>
        /// Initializes a new instance of the <see cref="InvoiceProcessingWorkflow"/> class.
        /// </summary>
        public InvoiceProcessingWorkflow()
        {
            this.InitializeComponent();
        }

        /// <summary>
        /// Gets the initial properties of the workflow.
        /// </summary>
        public SPWorkflowActivationProperties WorkflowProperties
        {
            get { return this.workflowProperties; }
        }

        /// <summary>
        /// Gets the invoice processing controller.
        /// </summary>
        public InvoiceProcessingController Controller
        {
            get { return this.controller; }
        }

        /// <summary>
        /// Gets the workflow context.
        /// </summary>
        public WorkflowContext Context
        {
            get
            {
                WorkflowContext ctx = new WorkflowContext();
                ctx.Initialize(this.workflowProperties);
                return ctx;
            }
        }

        #region Dependency Properties

        /// <summary>
        /// Gets or sets the create task special permissions.
        /// </summary>
        /// <value>
        /// The create task special permissions.
        /// </value>
        ////[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
        ////[BrowsableAttribute(true)]
        ////[CategoryAttribute("Misc")]
        ////public HybridDictionary CreateTaskSpecialPermissions
        ////{
        ////    get
        ////    {
        ////        return (HybridDictionary)this.GetValue(InvoiceProcessingWorkflow.CreateTaskSpecialPermissionsProperty);
        ////    }

        ////    set
        ////    {
        ////        this.SetValue(InvoiceProcessingWorkflow.CreateTaskSpecialPermissionsProperty, value);
        ////    }
        ////}

        #endregion Dependency Properties

        #region Code Conditions

        /// <summary>
        /// Sets the result of invoice is correct evaluation.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Workflow.Activities.ConditionalEventArgs"/> instance containing the event data.</param>
        private void InvoiceInfoIsCorrect(object sender, ConditionalEventArgs e)
        {
            e.Result = this.controller.InvoiceIsCorrect;
        }

        /// <summary>
        /// Sets the result of amount is less than first threshold evaluation.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Workflow.Activities.ConditionalEventArgs"/> instance containing the event data.</param>
        private void AmountIsLessThanFirstThreshold(object sender, ConditionalEventArgs e)
        {
            e.Result = this.controller.AmountIsLessThanFirstThreshold;
        }

        /// <summary>
        /// Sets the result of amount is less than second threshold evaluation.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Workflow.Activities.ConditionalEventArgs"/> instance containing the event data.</param>
        private void AmountIsGreaterThanSecondThreshold(object sender, ConditionalEventArgs e)
        {
            e.Result = this.controller.AmountIsGreaterThanSecondThreshold;
        }

        #endregion

        #region Handlers

        /// <summary>
        /// Handles the Invoked event of the WorkflowActivated control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Workflow.Activities.ExternalDataEventArgs"/> instance containing the event data.</param>
        private void WorkflowActivated_Invoked(object sender, ExternalDataEventArgs e)
        {
            this.controller = new InvoiceProcessingController(this);
        }

        /// <summary>
        /// Handles the ExecuteCode event of the SetInvoiceStatusAsWaitingForCorrectInfo control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void SetInvoiceStatusAsWaitingForCorrectInfo_ExecuteCode(object sender, EventArgs e)
        {
            this.controller.SetInvoiceStatus(Status.WaitingForCorrectInfo);
        }

        /// <summary>
        /// Handles the ExecuteCode event of the SetInvoiceStatusAsCorrect control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void SetInvoiceStatusAsCorrect_ExecuteCode(object sender, EventArgs e)
        {
            this.controller.SetInvoiceStatus(Status.Correct);
        }

        /// <summary>
        /// Handles the ExecuteCode event of the SetInvoiceStatusAsWaitingForArchived control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void SetInvoiceStatusAsWaitingForArchived_ExecuteCode(object sender, EventArgs e)
        {
            this.controller.SetInvoiceStatus(Status.WaitingForArchived);
        }

        /// <summary>
        /// Handles the ExecuteCode event of the SetInvoiceStatusAsArchived control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void SetInvoiceStatusAsArchived_ExecuteCode(object sender, EventArgs e)
        {
            this.controller.SetInvoiceStatus(Status.Archived);
        }

        #endregion
    }
}
